dependencies = [
"docopt 0.6.0 (git+https://github.com/burntsushi/docopt.rs#fc7ba2f1a5a351f7874257d880223d2ff5c75d36)",
"docopt_macros 0.6.0 (git+https://github.com/burntsushi/docopt.rs#fc7ba2f1a5a351f7874257d880223d2ff5c75d36)",
+ "flate2 0.0.1 (git+https://github.com/alexcrichton/flate2-rs#12593d1b9ccf09c2eabac176a6e233b171eed843)",
"hamcrest 0.1.0 (git+https://github.com/carllerche/hamcrest-rust.git#f0fd1546b0a7a278a12658ab8602b5c827cc3a42)",
"semver 0.0.1 (git+https://github.com/rust-lang/semver#c78b40d7fdf8acd99b503e6ce394fbcf9eb8982f)",
+ "tar 0.0.1 (git+https://github.com/alexcrichton/tar-rs#689bbc003ae47feae5bc99c53b56736e4ad994ba)",
"toml 0.1.0 (git+https://github.com/alexcrichton/toml-rs#8c128cb550ba66d4962cd81acca93857c605eaa0)",
"url 0.1.0 (git+https://github.com/servo/rust-url#23fb9ec22cca9d643ad2cce9894a947c005b7fe2)",
]
version = "0.1.0"
source = "git+https://github.com/lifthrasiir/rust-encoding#7e7950ddbd46428a439db3e2594fa78f0972ef2e"
+[[package]]
+name = "flate2"
+version = "0.0.1"
+source = "git+https://github.com/alexcrichton/flate2-rs#12593d1b9ccf09c2eabac176a6e233b171eed843"
+
[[package]]
name = "hamcrest"
version = "0.1.0"
version = "0.0.1"
source = "git+https://github.com/rust-lang/semver#c78b40d7fdf8acd99b503e6ce394fbcf9eb8982f"
+[[package]]
+name = "tar"
+version = "0.0.1"
+source = "git+https://github.com/alexcrichton/tar-rs#689bbc003ae47feae5bc99c53b56736e4ad994ba"
+
[[package]]
name = "toml"
version = "0.1.0"
[dependencies.semver]
git = "https://github.com/rust-lang/semver"
+[dependencies.tar]
+git = "https://github.com/alexcrichton/tar-rs"
+
+[dependencies.flate2]
+git = "https://github.com/alexcrichton/flate2-rs"
+
[[bin]]
name = "cargo"
test = false
$macro!(git_checkout)
$macro!(locate_project)
$macro!(new)
+ $macro!(package)
$macro!(read_manifest)
$macro!(run)
$macro!(test)
--- /dev/null
+use docopt;
+use cargo::ops;
+use cargo::core::{MultiShell};
+use cargo::util::{CliResult, CliError};
+use cargo::util::important_paths::find_root_manifest_for_cwd;
+
+docopt!(Options, "
+Assemble a the local package into a distributable tarball
+
+Usage:
+ cargo package [options]
+
+Options:
+ -h, --help Print this message
+ --manifest-path PATH Path to the manifest to compile
+ -v, --verbose Use verbose output
+
+", flag_manifest_path: Option<String>)
+
+pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
+ shell.set_verbose(options.flag_verbose);
+ let Options {
+ flag_manifest_path,
+ ..
+ } = options;
+
+ let root = try!(find_root_manifest_for_cwd(flag_manifest_path.clone()));
+ ops::package(&root, shell).map(|_| None).map_err(|err| {
+ CliError::from_boxed(err, 101)
+ })
+}
use semver;
use std::hash::Hash;
use std::fmt::{mod, Show, Formatter};
-use collections::hash;
+use std::hash;
use serialize::{
Encodable,
Encoder,
#![feature(default_type_params)]
#![deny(warnings)]
-extern crate collections;
-extern crate debug;
extern crate glob;
extern crate regex;
-extern crate semver;
extern crate serialize;
extern crate term;
extern crate time;
-extern crate url;
#[phase(plugin)] extern crate regex_macros;
#[phase(plugin, link)] extern crate log;
+extern crate semver;
extern crate docopt;
+extern crate flate2;
+extern crate tar;
+extern crate url;
extern crate toml;
#[cfg(test)] extern crate hamcrest;
--- /dev/null
+use std::io::File;
+
+use tar::Archive;
+use flate2::{GzBuilder, BestCompression};
+
+use core::source::Source;
+use core::{Package, MultiShell};
+use sources::PathSource;
+use util::{CargoResult, human, internal, ChainError, Require};
+
+pub fn package(manifest_path: &Path,
+ shell: &mut MultiShell) -> CargoResult<Path> {
+ let mut src = try!(PathSource::for_path(&manifest_path.dir_path()));
+ try!(src.update());
+ let pkg = try!(src.get_root_package());
+
+ let filename = format!("{}-{}.tar.gz", pkg.get_name(), pkg.get_version());
+ let dst = pkg.get_manifest_path().dir_path().join(filename);
+ try!(shell.status("Packaging", pkg.get_package_id().to_string()));
+ try!(tar(&pkg, &src, shell, &dst).chain_error(|| {
+ human("failed to prepare local package for uploading")
+ }));
+
+ Ok(dst)
+}
+
+fn tar(pkg: &Package, src: &PathSource, shell: &mut MultiShell,
+ dst: &Path) -> CargoResult<()> {
+
+ if dst.exists() {
+ return Err(human(format!("destination already exists: {}",
+ dst.display())))
+ }
+ let tmpfile = try!(File::create(dst));
+
+ // Prepare the encoder and its header
+ let encoder = GzBuilder::new().filename(dst.filename().unwrap())
+ .writer(tmpfile, BestCompression);
+
+ // Put all package files into a compressed archive
+ let ar = Archive::new(encoder);
+ for file in try!(src.list_files(pkg)).iter() {
+ let relative = file.path_relative_from(&dst.dir_path()).unwrap();
+ let relative = try!(relative.as_str().require(|| {
+ human(format!("non-utf8 path in source directory: {}",
+ relative.display()))
+ }));
+ let mut file = try!(File::open(file));
+ try!(shell.verbose(|shell| {
+ shell.status("Archiving", relative.as_slice())
+ }));
+ let path = format!("{}-{}/{}", pkg.get_name(),
+ pkg.get_version(), relative);
+ try!(ar.append(path.as_slice(), &mut file).chain_error(|| {
+ internal(format!("could not archive source file `{}`", relative))
+ }));
+ }
+
+ Ok(())
+}
pub use self::cargo_generate_lockfile::{generate_lockfile, write_resolve};
pub use self::cargo_generate_lockfile::{update_lockfile, load_lockfile};
pub use self::cargo_test::{run_tests, run_benches, TestOptions};
+pub use self::cargo_package::package;
mod cargo_clean;
mod cargo_compile;
mod cargo_doc;
mod cargo_generate_lockfile;
mod cargo_test;
+mod cargo_package;
pub static FRESH: &'static str = " Fresh";
pub static UPDATING: &'static str = " Updating";
pub static DOCTEST: &'static str = " Doc-tests";
+pub static PACKAGING: &'static str = " Packaging";
--- /dev/null
+use support::{project, execs};
+use support::{PACKAGING};
+use hamcrest::{assert_that, existing_file};
+
+fn setup() {
+}
+
+test!(simple {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/main.rs", r#"
+ fn main() { println!("hello"); }
+ "#);
+
+ assert_that(p.cargo_process("package"),
+ execs().with_status(0).with_stdout(format!("\
+{packaging} foo v0.0.1 ({dir})
+",
+ packaging = PACKAGING,
+ dir = p.url()).as_slice()));
+ assert_that(&p.root().join("foo-0.0.1.tar.gz"), existing_file());
+})
mod test_cargo_doc;
mod test_cargo_freshness;
mod test_cargo_generate_lockfile;
+mod test_cargo_package;